﻿// See https://aka.ms/new-console-template for more information
using System;
using System.IO;
using System.Security.AccessControl;
using System.Security.Principal;

class FileProtector
{
    public static void CreateLockedDownFile(string filePath)
    {
        try
        {
            // 确保目录存在
            Directory.CreateDirectory(Path.GetDirectoryName(filePath));

            // 创建空文件
            using (File.Create(filePath)) { }

            // 设置最高级别保护
            SetMaximumProtection(filePath);

            Console.WriteLine($"文件已创建并锁定: {filePath}");
        }
        catch (UnauthorizedAccessException)
        {
            Console.WriteLine("错误: 需要管理员权限运行此程序");
        }
        catch (Exception ex)
        {
            Console.WriteLine($"错误: {ex.Message}");
        }
    }

    private static void SetMaximumProtection(string filePath)
    {
        // 获取当前文件安全设置
        FileInfo fileInfo = new FileInfo(filePath);
        FileSecurity fSecurity = fileInfo.GetAccessControl();

        // 1. 禁用权限继承并清除所有继承的权限
        fSecurity.SetAccessRuleProtection(true, false);

        // 2. 移除所有现有权限规则
        var rules = fSecurity.GetAccessRules(true, true, typeof(NTAccount));
        foreach (FileSystemAccessRule rule in rules)
        {
            fSecurity.RemoveAccessRuleSpecific((FileSystemAccessRule)rule);
        }

        // 3. 设置最小必要权限
        // 只允许SYSTEM和创建者所有者完全控制
        fSecurity.AddAccessRule(new FileSystemAccessRule(
            new SecurityIdentifier(WellKnownSidType.LocalSystemSid, null),
            FileSystemRights.FullControl,
            AccessControlType.Allow));

        fSecurity.AddAccessRule(new FileSystemAccessRule(
            new SecurityIdentifier(WellKnownSidType.CreatorOwnerSid, null),
            FileSystemRights.FullControl,
            AccessControlType.Allow));

        // 4. 拒绝所有其他用户的任何访问（包括管理员组）
        fSecurity.AddAccessRule(new FileSystemAccessRule(
            new SecurityIdentifier(WellKnownSidType.BuiltinAdministratorsSid, null),
            FileSystemRights.FullControl,
            AccessControlType.Deny));

        fSecurity.AddAccessRule(new FileSystemAccessRule(
            new SecurityIdentifier(WellKnownSidType.WorldSid, null),
            FileSystemRights.FullControl,
            AccessControlType.Deny));

        // 5. 防止权限被修改
        fSecurity.AddAccessRule(new FileSystemAccessRule(
            new SecurityIdentifier(WellKnownSidType.LocalSystemSid, null),
            FileSystemRights.ChangePermissions,
            AccessControlType.Deny));

        fSecurity.AddAccessRule(new FileSystemAccessRule(
            new SecurityIdentifier(WellKnownSidType.CreatorOwnerSid, null),
            FileSystemRights.ChangePermissions,
            AccessControlType.Deny));

        // 6. 应用新的安全设置
        fileInfo.SetAccessControl(fSecurity);

        // 7. 设置文件属性为只读+系统文件（额外保护层）
        File.SetAttributes(filePath,
            FileAttributes.ReadOnly | FileAttributes.System);
    }

}

// 使用示例
class Program
{
    static void Main()
    {
        Create2();
    }

    public static void Create1() {
        // 需要以管理员身份运行此程序
        string protectedFile = @"C:\SecureData\TopSecret.txt";

        // 创建并锁定文件
        //   FileProtector.CreateLockedDownFile(protectedFile);

        // 验证文件是否受到保护
        try
        {
            FileInfo fileInfo = new FileInfo(protectedFile);

            // 尝试添加权限应该会失败
            var testSecurity = fileInfo.GetAccessControl(); //File.GetAccessControl(protectedFile);
            testSecurity.AddAccessRule(new FileSystemAccessRule(
                "Everyone",
                FileSystemRights.Read,
                AccessControlType.Allow));
            //  fileInfo.SetAccessControl(protectedFile, testSecurity);

            Console.WriteLine("警告: 仍能修改权限！");
        }
        catch (UnauthorizedAccessException)
        {
            Console.WriteLine("测试通过: 无法修改文件权限");
        }
    }
    public static void Create2() {

        try
        {
            string filePath = @"D:\path\file.txt";
            FileSecurityManager.LockFilePermissions(filePath);
           
        }
        catch (Exception ex)
        {
            Console.WriteLine($"操作失败: {ex.Message}");
           
        }
        Console.ReadKey();
    }
}